package com.block.product.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.block.common.constant.AppRspCodeConstant;
import com.block.common.constant.RedisKeyConstant;
import com.block.common.exception.NotifyExceptionService;
import com.block.common.service.LogFactory;
import com.block.common.vo.ResponseVo;
import com.block.db.common.vo.BaseUserInfoVo;
import com.block.db.entity.ProductInfo;
import com.block.db.entity.ProductMemberUnion;
import com.block.db.mapper.ProductMemberUnionMapper;
import com.block.product.factory.UnionTypeFactory;
import com.block.product.model.dto.ProdUnionDTO;
import com.block.product.service.IProductMemberUnionService;
import com.block.product.service.IProductUnionService;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 
 * @since 2022-07-31
 */
@Service
public class ProductMemberUnionServiceImpl extends ServiceImpl<ProductMemberUnionMapper, ProductMemberUnion> implements IProductMemberUnionService {

    private static Logger log = LogFactory.getCommLog();

    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Autowired
    IProductUnionService productUnionService;
    @Autowired
    NotifyExceptionService notifyExceptionService;

    @Override
    public String getUnionProductByUserId(Long userId, Long productId){

        String productIdStr = String.valueOf(productId);
        String redisKey = StrUtil.format(RedisKeyConstant.PRODUCT_MEMBER_UNION_PROD_INFO, productIdStr, userId);
        String detailUrl = stringRedisTemplate.opsForValue().get(redisKey);
        return detailUrl;
    }

    @Override
    public boolean updateInfo(ProductMemberUnion memberUnion) {

        try {
            if (StrUtil.equals("SUCCESS", memberUnion.getStatus())){
                String productIdStr = String.valueOf(memberUnion.getProductId());
                String redisKey = StrUtil.format(RedisKeyConstant.PRODUCT_MEMBER_UNION_PROD_INFO, productIdStr, memberUnion.getUserId());
                stringRedisTemplate.opsForValue().set(redisKey, memberUnion.getProductUrl(), 1L, TimeUnit.DAYS);
            }
            boolean saveRes = this.updateById(memberUnion);
            return saveRes;
        }catch (Exception exception){
            exception.printStackTrace();
        }
        return false;
    }

    /**
     * 查询用户联登产品撞库信息
     * 1.已经保证属于联登产品，并且
     * 2.给联登产品一天的展示时间（是否展示联登产品信息）
     *  如果展示，是否有产品url信息展示
     *  如果不展示，怎么返回标志
     */
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
    public ProdUnionDTO findProductUnionMatchResult(ProductInfo productInfo, BaseUserInfoVo userInfoVo) {

        ProdUnionDTO prodUnionDTO = new ProdUnionDTO();
        try {

            String productIdStr = String.valueOf(productInfo.getId());
            String redisKey = StrUtil.format(RedisKeyConstant.PRODUCT_MEMBER_UNION_PROD_INFO, productIdStr, userInfoVo.getUid());
            // 查询用户/产品的联登信息，查缓存
            String cacheProductUrl = stringRedisTemplate.opsForValue().get(redisKey);
            if (StrUtil.isNotEmpty(cacheProductUrl)){
                // 产品联登信息
                prodUnionDTO.setShowFlag(true);
                prodUnionDTO.setProdUrl(cacheProductUrl);
                return prodUnionDTO;
            }

            // 查到用户/产品 的联登信息 db
            ProductMemberUnion memberUnion = this.baseMapper.getEntryByUserIdAndProductIdLock(userInfoVo.getUid(), productInfo.getId());
            if (ObjectUtil.isNotEmpty(memberUnion) ){
                log.info("【联登产品信息】联登记录不为空【memberUnion】{}", JSON.toJSONString(memberUnion));
               if (StrUtil.equals(memberUnion.getStatus(), "INIT") || StrUtil.equals(memberUnion.getStatus(), "SUCCESS")){
                   prodUnionDTO.setShowFlag(true);
                   prodUnionDTO.setProdUrl(memberUnion.getProductUrl());
               }else{
                   prodUnionDTO.setShowFlag(false);
               }
                return prodUnionDTO;
            }

            // 撞库联登记录为空，则进行撞库操作
            // 用户进行撞库操作
            ResponseVo responseVo = UnionTypeFactory.getService(productInfo.getFactoryType()).matchUserInfo(productInfo, userInfoVo);
            log.info("【联登产品信息】联登撞库完成【responseVo】{}", JSON.toJSONString(responseVo));

            memberUnion = new ProductMemberUnion();
            memberUnion.setProductId(productInfo.getId());
            memberUnion.setUserId(userInfoVo.getUid());
            if (!AppRspCodeConstant.SUCCESS.equals(responseVo.getRspCode())){
                // 撞库失败，保存失败记录
                memberUnion.setStatus("FAILED");
                prodUnionDTO.setShowFlag(false);
            }else{
                // 撞库成功，展示用户信息
                memberUnion.setStatus("INIT");
                prodUnionDTO.setShowFlag(true);
            }
            memberUnion.setMatchResult(responseVo.getRspMsg());
            boolean save = this.save(memberUnion);
            log.info("【联登产品信息】保存联登/撞库记录【save】{}【memberUnion】{}", save, JSON.toJSONString(memberUnion));
        }catch (Exception exception){
            exception.printStackTrace();
            log.info("【联登产品信息】发生异常", exception);
            prodUnionDTO.setShowFlag(false);
            String message = StrUtil.format("产品ID：{}；产品名称：{}；mobile: {}", productInfo.getId(), productInfo.getProductName(), userInfoVo.getMobile());
            notifyExceptionService.notifyNoticeInfo("PROD_UNION", "产品联登撞库异常", message, exception);
        }
        return prodUnionDTO;
    }


}
